#ifndef CONNECT_H
#define CONNECT_H

class Server;
class MyOverlapped;
class WebServiceCall;

#ifndef CONNECT_IBUF
#error "CONNECT_IBUF is not defined!"
#endif

#ifndef CONNECT_OBUF
#error "CONNECT_OBUF is not defined!"
#endif

struct localCurrency;
class XMLTranslator;

class Connection
{
public:
	Connection(Server*, SOCKET client);
	virtual ~Connection();

	virtual bool8	initOk();

	void	ready();							// for Server use ONLY
	void	processIO(uint32 Amt, int32 Err);	// for Server use ONLY
	void	closesocket();						// for Server use ONLY

	void	lock();								// for Server use ONLY
	void	unlock();							// for Server use ONLY

	void	readyToUnPause();					// for Server use ONLY

	bool8	isStale(uint32 staleAge);			// for Server use ONLY

	Connection* getNext();
	Connection* getPrev();
	void setNext(Connection*);
	void setPrev(Connection*);

	void getClientIP(String& ipaddress);
	void getClientIP(char* buf, int32 maxBufSizeIncludingNull);

	virtual bool8 readyForDeath();

	Server* getServer() { return server; };

	virtual void finish() { };

	virtual bool8  getLocale( localCurrency* lc, int32* chipValues, int32 numChipValues )
	{
		return false;
	}

	WebServiceCall* wsCall();
	
	// The current language
	void   SetLanguage( const String& sLang );
	const  String& GetLanguage() const;
	virtual bool8  ParseXMLLogin();
	virtual bool8 getCampaignMessage();

	String getCurrency() { return m_sCurrency; };		// CSN-11204: return currency in Login
	
protected:
	virtual bool8 getResponse();
	virtual bool8 moreToSend();
	void pauseResponse(bool8);
	
	

	bool8 isServerStopping();
	char* getServerStopMsg();

	void close();	// phase 1: start closing process
	void dead();	// phase 2: closing done, ready to be destroyed

	bool8 isXmlMessage( const uint8* const buf ) const;
	bool8 isCompleteXmlMessage( const uint8* const  buf, uint32 amt ) const;
	virtual void allocateXMLTranslator( XMLTranslator** target );
	int32 calculateTranslationUsed(const uint8* const message);

	String m_sCurrency;	// CSN-11204: return currency in Login

private:
	bool postRead();
	bool postWrite();

	void checkOverwrite();

private:
	Server*				server;
	Connection			*prev, *next;
	SOCKET				client;
	MyOverlapped*		over;
	int32				state;
	PCRITICAL_SECTION	iomutex;
	uint32				reqTime;

protected:
	enum IOBufSizes { INMAX = CONNECT_IBUF, OUTMAX = CONNECT_OBUF };

	enum HistorySize { HISTORY_DEPTH = 2 };
	enum OverWriteMagic { OVERWRITE_1 = 0xABCD, OVERWRITE_2 = 0xEFAB, OVERWRITE_DEAD = 0xDEAD };

	static const char* const sXmlDeclaration;
	bool8				processingXMLMessage;
	XMLTranslator*		xmlTranslator;

	uint8			ibuf[INMAX+1];
	volatile uint32 overwriteDetector1;

	uint8			obuf[2*OUTMAX+1];
	volatile uint32 overwriteDetector2;

	int32           overwriteCount;

	int32			iused;
	int32			oused;

	// Used to keep history (hst) of ProcessIO
	uint8			hstbuf[HISTORY_DEPTH][INMAX+1];
	int32           hstused[HISTORY_DEPTH];
	int32           hstAmt[HISTORY_DEPTH];

	// Used to keep history (hst) of PostRead
	int32           hstReadStart[HISTORY_DEPTH];
	int32           hstReadAvail[HISTORY_DEPTH];
	int32           hstReadLen[HISTORY_DEPTH];

	int32			shutdownSent;
	String          m_sLang;
};

inline Connection*
Connection::getNext()
{
	return next;
}

inline Connection*
Connection::getPrev()
{
	return prev;
}

inline void
Connection::setNext(Connection* Conn)
{
	next = Conn;
}

inline void
Connection::setPrev(Connection* Conn)
{
	prev = Conn;
}
inline bool8
Connection::moreToSend()
{
	return false;
}

inline bool8
Connection::readyForDeath()
{
	//
	// override this to short-circuit being destroyed (and return false)
	// then, when ready for destruction, call dead().
	//
	return true;
}

inline 
void   Connection::SetLanguage( const String& sLang ) 
{
	m_sLang = sLang;
}
//RPFX 8.4.1
inline
bool8 Connection::getCampaignMessage()
{
return false;
}
inline 
const  String& Connection::GetLanguage() const 
{
	return m_sLang;
}

#endif
